/*
 * Copyright (c) 2020. André Mion
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andremion.louvre.home;

import com.andremion.louvre.ResourceTable;
import com.andremion.louvre.StoragePermissionActivity;
import com.andremion.louvre.annotation.NonNull;
import com.andremion.louvre.data.Album;
import com.andremion.louvre.loader.LoaderCallback;
import com.andremion.louvre.util.Utils;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.data.resultset.ResultSet;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.utils.net.Uri;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import static com.andremion.louvre.Louvre.*;


/**
 * GalleryActivity
 */
public class GalleryActivity extends StoragePermissionActivity implements GalleryAdapter.Callbacks, Component.ClickedListener {
    private static final int DEFAULT_MAX_SELECTION = 1;
    private static final int DEFAULT_THEME_COLOR = 0;
    private EventHandler mEventHandler;

    /**
     * Start the Gallery Activity with additional launch information.
     *
     * @param activity        Context to launch activity from.
     * @param requestCode     If >= 0, this code will be returned in onActivityResult() when the activity exits.
     * @param maxSelection    The max count of image selection
     * @param selection       The current image selection
     * @param mediaTypeFilter The media types that will display
     * @param mThemeColor     Color
     */
    public static void startActivity(Ability activity, int requestCode, int mThemeColor,
                                     int maxSelection,
                                     List<Uri> selection,
                                     String... mediaTypeFilter) {
        Intent intent = buildIntent(activity.getContext(), mThemeColor, maxSelection, selection, mediaTypeFilter);
        activity.startAbilityForResult(intent, requestCode);
    }

    @NonNull
    private static Intent buildIntent(Context context, int mThemeColor, int maxSelection, List<Uri> selection, String[] mediaTypeFilter) {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(context.getBundleName())
                .withAbilityName(GalleryActivity.class.getName())
                .build();
        intent.setOperation(operation);

        intent.setParam(EXTRA_THEME_COLOR, mThemeColor);
        if (maxSelection > 0) {
            intent.setParam(EXTRA_MAX_SELECTION, maxSelection);
        }
        if (selection != null) {
            intent.setParam(EXTRA_SELECTION, new LinkedList<>(selection));
        }
        if (mediaTypeFilter != null && mediaTypeFilter.length > 0) {
            intent.setParam(EXTRA_MEDIA_TYPE_FILTER, mediaTypeFilter);
        } else {
            intent.setParam(EXTRA_MEDIA_TYPE_FILTER, new String[]{});
        }
        return intent;
    }

    private GalleryAdapter mGalleryAlbumAdapter = null;
    private ArrayList<Album> albums = new ArrayList<>();
    private Component mEmptyView;
    private StackLayout toolBarLayout;
    private TableLayoutManager mLayoutManager;
    private ListContainer mRecyclerView;
    private com.andremion.louvre.loader.AlbumLoader albumLoader;
    List<Uri> selection;
    int REQUEST_CODE = 221;
    private int mThemeColor;
    GalleryAdapter.Callbacks mCallBack = new GalleryAdapter.Callbacks() {
        @Override
        public void onBucketClick(long bucketId, String label) {
            GalleryFragment.startActivity(GalleryActivity.this, REQUEST_CODE,
                    getIntent().getIntParam(EXTRA_THEME_COLOR, DEFAULT_THEME_COLOR),
                    getIntent().getIntParam(EXTRA_MAX_SELECTION, DEFAULT_MAX_SELECTION),
                    (List<Uri>) getIntent().getSerializableParam(EXTRA_SELECTION),
                    getIntent().getStringArrayParam(EXTRA_MEDIA_TYPE_FILTER));
        }

        @Override
        public void onMediaClick(Component imageView, Component checkView, long bucketId, int position) {
        }

        @Override

        public void onSelectionUpdated(int count) {
        }

        @Override
        public void onMaxSelectionReached() {
        }

        @Override
        public void onWillExceedMaxSelection() {
        }
    };

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_activity_gallery);
        mThemeColor = getIntent().getIntParam(EXTRA_THEME_COLOR, 0);

        mGalleryAlbumAdapter = new GalleryAdapter(getContext(), mCallBack, albums);
        selection = (List<Uri>) getIntent().getSerializableParam(EXTRA_SELECTION);
        albumLoader = new com.andremion.louvre.loader.AlbumLoader(this);
        albumLoader.setSelectionArgsForSingleMediaType(getIntent().getStringArrayParam(EXTRA_MEDIA_TYPE_FILTER));

        toolBarLayout = (StackLayout) findComponentById(ResourceTable.Id_toolBarLayout);
        if (mThemeColor == 0) {
            getWindow().setStatusBarColor(Utils.getColor(getContext(), ResourceTable.Color_default_theme_color));
        } else {
            getWindow().setStatusBarColor(Utils.getColor(getContext(), mThemeColor));
            ShapeElement element = new ShapeElement();
            element.setRgbColor(RgbColor.fromArgbInt(Utils.getColor(getContext(),
                    mThemeColor)));
            toolBarLayout.setBackground(element);
        }
        mEmptyView = findComponentById(ResourceTable.Id_empty);
        mLayoutManager = new TableLayoutManager();
        mLayoutManager.setColumnCount(4);
        mRecyclerView = (ListContainer) findComponentById(ResourceTable.Id_list_container);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemProvider(mGalleryAlbumAdapter);
        askForPermission();
    }

    private void getAlAlbums() {
        albumLoader.setLoaderCallback(new LoaderCallback<ResultSet>() {
            @Override
            public void setCallback(ResultSet resultSet) {
                ArrayList<Album> albumArrayList = new ArrayList<>();
                if (resultSet.getRowCount() > 1 && resultSet.goToFirstRow()) {
                    do {
                        Album a = Album.valueOf(resultSet);
                        albumArrayList.add(a);
                    } while (resultSet.goToNextRow());
                    albums.clear();
                    albums.addAll(albumArrayList);
                    loadRefreshAdapter();
                    resultSet.close();
                }
            }
        });
        albumLoader.load();
    }

    private void loadRefreshAdapter() {
        mEventHandler = new EventHandler(EventRunner.getMainEventRunner());
        mEventHandler.postTask(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.setItemProvider(mGalleryAlbumAdapter);
                mGalleryAlbumAdapter.notifyDataChanged();
                updateEmptyState(mGalleryAlbumAdapter);
            }
        }, 1);
    }

    private void updateEmptyState(BaseItemProvider mAdapter) {
        mRecyclerView.setVisibility(mAdapter.getCount() > 0 ? Component.VISIBLE : Component.INVISIBLE);
        mEmptyView.setVisibility(mAdapter.getCount() > 0 ? Component.INVISIBLE : Component.VISIBLE);
    }

    @Override
    public void onPermissionGranted() {
        getAlAlbums();
    }


    @Override
    public void onBucketClick(long bucketId, String label) {
    }

    @Override
    public void onMediaClick(Component imageView, Component checkView, long bucketId, int position) {
    }

    @Override
    public void onSelectionUpdated(int count) {
    }

    @Override
    public void onMaxSelectionReached() {
        new ToastDialog(getContext()).setText(Utils.getString(getContext(),
                ResourceTable.String_activity_gallery_will_exceed_max_selection)).show();
    }

    @Override
    public void onWillExceedMaxSelection() {
        new ToastDialog(getContext()).setText(Utils.getString(getContext(),
                ResourceTable.String_activity_gallery_will_exceed_max_selection)).show();
    }


    @Override
    public void onClick(Component component) {
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            Intent data = new Intent();
            data.setParam(EXTRA_SELECTION, new LinkedList<>((List<Uri>) resultData
                    .getSerializableParam(EXTRA_SELECTION)));
            setResult(RESULT_OK, data);
            onBackPressed();
        } else {
            super.onAbilityResult(requestCode, resultCode, resultData);
        }
    }
}
